package com.gestionabsences.form;

import com.gestionabsences.beans.MapMatters;
import com.gestionabsences.beans.ResultRequest;
import com.gestionabsences.config.DAOFactory;
import com.gestionabsences.database.ToolsRequest;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;

/**
 *
 * @author matt
 */
public class FormStudent {
    public static final String CHAMP_MATIERE = "matiere";
    public static final String CHAMP_TYPE_SEANCE = "typeSeance";
    public static final String CHAMP_OPTION = "option";
    public static final String CHAMP_ERREUR = "erreur";
    
    private Map<String, String> erreurs;
    private MapMatters listeMatieres;
    private DAOFactory dao;
    private String ine;
    
    private String formerValMatiere;
    private String formerValTypeSeance;
    private String formerValOption;
    
    public FormStudent(DAOFactory dao, MapMatters listMatieres, String ine) {
	this.erreurs = new HashMap<String, String>();
	this.listeMatieres = listMatieres;
	this.dao = dao;
	this.ine = ine;
    }
    
    public ResultRequest creationResultat( HttpServletRequest request ) {
	
	String matiere = getValeurChamp( request, CHAMP_MATIERE );
	String typeSeance = getValeurChamp( request, CHAMP_TYPE_SEANCE );
	String option = getValeurChamp( request, CHAMP_OPTION );

	
	try {
            validationTypeSeance( typeSeance );
        } catch ( Exception e ) {
            setErreur( CHAMP_TYPE_SEANCE, e.getMessage() );
        }
	
	try {
            validationMatiere( matiere );
        } catch ( Exception e ) {
            setErreur( CHAMP_MATIERE, e.getMessage() );
        }
	
	try {
            validationOption( option );
        } catch ( Exception e ) {
            setErreur( CHAMP_OPTION, e.getMessage() );
        }
	
	
	ResultRequest res = null;
	
	if( erreurs.isEmpty() ) {
	    formerValMatiere = matiere;
	    formerValOption = option;
	    formerValTypeSeance = option;
	    
	    res = createResultFromArgs(matiere, typeSeance, option);
	    if( !res.isResultatPresent() ) {
		res = null;
	    }
	}

	return res;
    }
    
    public String getFormerValMatiere() {
	return this.formerValMatiere;
    }
    
    public String getFormerValOption() {
	return this.formerValOption;
    }
    
    public String getFormerValTypeSeance() {
	return this.formerValTypeSeance;
    }
    
    private ResultRequest createResultFromArgs(String matiere, String typeSeance, String option) {
	ArrayList<String> tabColonnes = new ArrayList<String>();
	tabColonnes.add("id_seance");	
	
	String paramVarMatiere = ", matiere";
	String paramVarIsA = ", isa";
	String paramVarCredibilite = ", CAST(A.credibilite AS VARCHAR(5)) credibilite";
	String paramWhereMatiere = "";
	String paramWhereIsA = "";
	String paramWhereCredibilite = "";
	
	boolean pMatiere = false;
	boolean pTypeSeance = false;
	boolean pCredibilite = false;
	
	if(matiere.compareTo("ALL") != 0) {
	    paramVarMatiere = "";
	    paramWhereMatiere = " A.matiere = '" + matiere + "' ";
	    pMatiere = true;
	} else {
	    tabColonnes.add("matiere");
	}
	
	if(typeSeance.compareTo("ALL") != 0) {
	    paramVarIsA = "";
	    paramWhereIsA = " A.isa = '" + typeSeance + "' ";
	    pTypeSeance = true;
	} else {
	    tabColonnes.add("isa");
	}
	
	tabColonnes.add("salle");
	tabColonnes.add("heure");
	tabColonnes.add("nom_enseignant");
	tabColonnes.add("prenom_enseignant");
	tabColonnes.add("justification");
	
	if(option.compareTo("ALL") != 0)
	{
	    if(option.compareTo("withJustifications") == 0) {
		paramWhereCredibilite = " A.credibilite > 0 ";
	    } else {
		paramWhereCredibilite = " A.credibilite = 0 ";
	    }
	    paramVarCredibilite = "";
	    pCredibilite = true;
	} else {
	    tabColonnes.add("credibilite");
	}
	
	String sql_all_request = "SELECT CAST(A.id_seance AS VARCHAR(10)) id_seance" + paramVarMatiere + paramVarIsA + ", A.salle, CAST(A.heure AS VARCHAR(20)) heure, A.nom_enseignant, A.prenom_enseignant, A.justification" + paramVarCredibilite + " FROM getAbsences(?) A";
	sql_all_request += ( (pCredibilite || pMatiere || pTypeSeance) ? " WHERE" : "");
	sql_all_request += paramWhereMatiere + ( (pMatiere && pTypeSeance || pMatiere && pCredibilite) ? "AND" : "");
	sql_all_request += paramWhereIsA + ( (pCredibilite && pTypeSeance) ? "AND" : "") + paramWhereCredibilite + ";";
	
	
	Connection connexion = null;
	ResultRequest res = null;
	
	try {
	    connexion = dao.getConnection();
	    
	    PreparedStatement preparedStatement = null;
	    ResultSet resultSet = null;
	
	    try {
		preparedStatement = ToolsRequest.prepareRequest( connexion, sql_all_request, false, ine);
		
		System.out.println( preparedStatement.toString() );
		//setErreur( CHAMP_ERREUR, preparedStatement.toString() );
		resultSet = preparedStatement.executeQuery();
		
		res = new ResultRequest(resultSet, tabColonnes.toArray());
				
	    } catch(Exception e) {
		setErreur( CHAMP_ERREUR, preparedStatement.toString() + " => " + e.getMessage() );
	    }
	    finally {
		ToolsRequest.close(preparedStatement, resultSet);
	    }
	} catch (SQLException e) {
	    setErreur( CHAMP_ERREUR, e.getMessage() );
	}
	finally {
	    ToolsRequest.close(connexion);
	}
	
	return res;
    }
    
    private void validationTypeSeance(String typeSeance) throws Exception {
	final String TYPE1 = "COURS";
	final String TYPE2 = "TPS";
	final String TYPE3 = "TDS";
	final String TYPE4 = "ALL";
	
	if( typeSeance.compareTo(TYPE1) != 0 && typeSeance.compareTo(TYPE2) != 0 && typeSeance.compareTo(TYPE3) != 0 && typeSeance.compareTo(TYPE4) != 0) {
	    throw new Exception( "Le type '" + typeSeance + "' n'existe pas." );
	}
    }
    
    private void validationOption(String option) throws Exception {
	final String OPTION1 = "ALL";
	final String OPTION2 = "withJustifications";
	final String OPTION3 = "withoutJustifications";
	
	if( option.compareTo(OPTION1) != 0 && option.compareTo(OPTION2) != 0 && option.compareTo(OPTION3) != 0 ) {
	    throw new Exception( "L'option '" + option + "' n'est pas valable." );
	}
    }
    
    private void validationMatiere( String nomMatiere ) throws Exception {
        
	boolean res = false;
	final String ATT_TOUS = "ALL";
	
	Iterator iterator = this.listeMatieres.entrySet().iterator();
	while (iterator.hasNext()) {
	    Map.Entry mapEntry = (Map.Entry) iterator.next();
	    if( nomMatiere.compareTo( (String) mapEntry.getValue() ) == 0 ) {
		res = true;
	    }
	}
	
	if(nomMatiere.compareTo(ATT_TOUS) == 0) {
	    res = true;
	}
	
	if(!res) {
	    throw new Exception( "Le nom de matière spécifié n'existe pas." );
	}
    }
    
    public Map<String, String> getErreurs() {
        return erreurs;
    }
    
    private void setErreur( String champ, String message ) {
	String previous = erreurs.get(champ);
	if(previous != null) {
	    erreurs.put( champ, previous + message );
	}
	else {
	    erreurs.put( champ, message );
	}
	
    }
    
    private static String getValeurChamp( HttpServletRequest request, String nomChamp ) {
        String valeur = request.getParameter( nomChamp );
        if ( valeur == null || valeur.trim().length() == 0 ) {
            return null;
        } else {
            return valeur;
        }
    }
}
